/*
 * A widget for display video.
 * Copyright by trung.truong78@gmail.com 
 */
package vn.com.tiz.DocumentZ.view;

import java.io.IOException;
import java.util.Map;

import vn.com.tiz.DocumentZ.R;
import vn.com.tiz.DocumentZ.utils.LogTools;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.GpsStatus.NmeaListener;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.SeekBar;
import android.widget.VideoView;

/**
 * A custom video view widget.
 * @author trungtt
 *
 */

public class VideoViewer extends FrameLayout implements
 OnPreparedListener, OnVideoSizeChangedListener {

	//VideoView videoView;
	 private MediaPlayer mMediaPlayer;
	 private SurfaceView mPreview;
	 private SurfaceHolder m_holder;
	 private String path;
	 private Uri         mUri;
	 
	 // all possible internal states
	    private static final int STATE_ERROR              = -1;
	    private static final int STATE_IDLE               = 0;
	    private static final int STATE_PREPARING          = 1;
	    private static final int STATE_PREPARED           = 2;
	    private static final int STATE_PLAYING            = 3;
	    private static final int STATE_PAUSED             = 4;
	    private static final int STATE_PLAYBACK_COMPLETED = 5;
	    private static final int STATE_SUSPEND            = 6;
	    private static final int STATE_RESUME             = 7;
	    private static final int STATE_SUSPEND_UNSUPPORTED = 8;

	    // mCurrentState is a VideoView object's current state.
	    // mTargetState is the state that a method caller intends to reach.
	    // For instance, regardless the VideoView object's current state,
	    // calling pause() intends to bring the object to a target state
	    // of STATE_PAUSED.
	    private int mCurrentState = STATE_IDLE;
	    private int mTargetState  = STATE_IDLE;
	    
	    
	 
	  private static final String TAG = "MediaPlayerDemo";
	    private int mVideoWidth;
	    private int mVideoHeight;
	    private int         mDuration;
	    private int         mCurrentBufferPercentage;
	    
	    
	    private Bundle extras;
	    private static final String MEDIA = "media";
	    private static final int LOCAL_AUDIO = 1;
	    private static final int STREAM_AUDIO = 2;
	    private static final int RESOURCES_AUDIO = 3;
	    private static final int LOCAL_VIDEO = 4;
	    private static final int STREAM_VIDEO = 5;
	    private boolean mIsVideoSizeKnown = false;
	    private boolean mIsVideoReadyToBePlayed = false;
	    
	    private boolean isMute = false;
	    private int currentVolume;
	   // LinearLayout lnearControl;
	    
	    private SurfaceHolder.Callback holder_callback = new SurfaceHolder.Callback() {
			
			public void surfaceDestroyed(SurfaceHolder holder) {
				// TODO Auto-generated method stub
				
			}
			
			public void surfaceCreated(SurfaceHolder holder) {
				// TODO Auto-generated method stub
				Log.d("TrungTT","Surface create...");
				m_holder = holder;
	            //resume() was called before surfaceCreated()
	            if (mMediaPlayer != null && mCurrentState == STATE_SUSPEND
	                   && mTargetState == STATE_RESUME) {
	                mMediaPlayer.setDisplay(m_holder);
	                resume();
	            } else {
	            	
	            	Log.d("TrungTT","Surface create and openvideo()...");
	                openVideo();
	            }
			}
			
			public void surfaceChanged(SurfaceHolder holder, int format, int width,	int height) {
				Log.d("TrungTT","Surface change...");
				// TODO Auto-generated method stub
				m_holder = holder;
				
				//m_holder.setSizeFromLayout();
				//requestLayout();
			    //invalidate();
			}
		};
	
	public VideoViewer(Context context){
		super(context);		
		
		mPreview = new SurfaceView(context);
		//LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
		LayoutParams lp = new LayoutParams(400,300);
		lp.gravity = Gravity.CENTER;
		mPreview.setLayoutParams(lp);
		mPreview.setBackgroundResource(R.drawable.video_thumb);
		
		addView(mPreview);
		setBackgroundColor(Color.CYAN);
		//setGravity(Gravity.CENTER);		
		//setPadding(10, 10, 10, 10);
		//mPreview.setBackgroundColor(Color.BLUE);
		initVideo();
		//initPlayer();
		
		//mMediaPlayer.
		createBarControl();
		//AudioManager au = new AudioManager
		
		setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Log.d("TrungTT","click...");
			}
		});
		
		
		//mPreview.
		
	}
	
	private void createBarControl(){
		LinearLayout lnearControl = new LinearLayout(getContext());
		lnearControl.setWeightSum(10);
		
		final Button btnPlay = new Button(getContext());
		btnPlay.setText(">");
		//LayoutParams lp = new android.view.ViewGroup.LayoutParams(100,50);
		//lp1.gravity = Gravity.BOTTOM;
		android.widget.LinearLayout.LayoutParams lp = new android.widget.LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
		//btnPlay.setGravity(Gravity.BOTTOM);
		lp.weight = 1;		
		btnPlay.setLayoutParams(lp);
		//btnPlay.setw
		btnPlay.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//video.play();
				if(btnPlay.getText().toString().equalsIgnoreCase(">")){
					resume();
					btnPlay.setText("||");
				}else{
					pause();
					btnPlay.setText(">");
				}
			}
		});
		
		SeekBar seekbar = new SeekBar(getContext());
		lp = new android.widget.LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);		
		lp.weight = 8;		
		seekbar.setLayoutParams(lp);
		//mMediaPlayer.get		
		
		final Button btnMute = new Button(getContext());
		btnMute.setText("Mute");

		lp = new android.widget.LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);		
		lp.weight = 1;		
		btnMute.setLayoutParams(lp);
		
		//final boolean isMute = false;
		
		btnMute.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//video.play();
				//mMediaPlayer.get
				//mMediaPlayer.
				//mMediaPlayer.setVolume(0, 0);
				AudioManager au = (AudioManager)v.getContext().getSystemService(Context.AUDIO_SERVICE);
				
				if(!isMute){
					//mute
					btnMute.setText("UnMute");
					au.setStreamMute(AudioManager.STREAM_MUSIC, true);
					isMute = true;
					
					mMediaPlayer.setVolume(0, currentVolume);
					
				}else{
					//unmute
					btnMute.setText("Mute");
					currentVolume = au.getStreamVolume(AudioManager.STREAM_MUSIC);
					au.setStreamMute(AudioManager.STREAM_MUSIC, false);
					isMute = false;
					
				}
				
				
			}
		});
		
		LayoutParams lp1 = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
		lp1.gravity = Gravity.BOTTOM;
		lnearControl.setLayoutParams(lp1);
		
		lnearControl.addView(btnPlay);
		lnearControl.addView(seekbar);
		lnearControl.addView(btnMute);
		
		lnearControl.setGravity(Gravity.CENTER);
		
		addView(lnearControl);
	}
	
	private void playVideo(){
		
	}
	
	
	public void refreshLayout(){
		m_holder.setSizeFromLayout();
		requestLayout();
	    invalidate();
	}
	
	private void initVideo(){
		mVideoWidth = 0;
        mVideoHeight = 0;
        m_holder = mPreview.getHolder();
        m_holder.addCallback(holder_callback);
        m_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        setFocusable(true);
        setFocusableInTouchMode(true);
        requestFocus();
        mCurrentState = STATE_IDLE;
        mTargetState  = STATE_IDLE;
	}
	
	 private boolean isInPlaybackState() {
	        return (mMediaPlayer != null &&
	                mCurrentState != STATE_ERROR &&
	                mCurrentState != STATE_IDLE &&
	                mCurrentState != STATE_PREPARING);
	    }
		
	 private void initPlayer() {

		 try {
	            mMediaPlayer = new MediaPlayer();
	            mMediaPlayer.setOnPreparedListener(this);
	            mMediaPlayer.setOnVideoSizeChangedListener(this);
	            mMediaPlayer.setDisplay(m_holder);
	            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
	            mMediaPlayer.setScreenOnWhilePlaying(true);
	            //mMediaPlayer.prepareAsync();
	            //mCurrentState = STATE_PREPARING;	     
	        } catch (Exception ex) {
	            Log.w("TrungTT", "init player fail: ", ex);
	        }
	    }

	 private void openVideo1(){
		 
		 //initPlayer();
		 
		  if (mUri == null || m_holder == null) {
	            return;
	        }
	        Intent i = new Intent("com.android.music.musicservicecommand");
	        i.putExtra("command", "pause");
	        getContext().sendBroadcast(i);
	        release(false);
	        
	        try {
	            mDuration = -1;
	            mCurrentBufferPercentage = 0;                        
	            if(mMediaPlayer == null){
	            	Log.d("TrungTT","Media null");
	            }
	            
	            if(mUri == null){
	            	LogTools.debug("URi null");
	            }
	            mMediaPlayer.setDataSource(this.getContext(), mUri);            
	            //mMediaPlayer.setDisplay(m_holder);
	            //mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
	            //mMediaPlayer.setScreenOnWhilePlaying(true);
	            mMediaPlayer.prepareAsync();
	            // we don't set the target state here either, but preserve the
	            // target state that was there before.
	            mCurrentState = STATE_PREPARING;
	            //attachMediaController();
	        } catch (Exception ex) {
	            Log.w(TAG, "Unable to open content: ", ex);
	            return;
	        } 
	 }

	private void openVideo() {
		
        if (mUri == null || m_holder == null) {
            // not ready for playback just yet, will try again later
        	LogTools.debug("open video with null value...");
            return;
        }
        //Lod.
        // Tell the music playback service to pause
        // TODO: these constants need to be published somewhere in the framework.
        Intent i = new Intent("com.android.music.musicservicecommand");
        i.putExtra("command", "pause");
        getContext().sendBroadcast(i);

        // we shouldn't clear the target state, because somebody might have
        // called start() previously
        release(false);
        
        try {
        	//m_holder
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mDuration = -1;
            //mMediaPlayer.setOnCompletionListener(this);
            //mMediaPlayer.setOnErrorListener(mErrorListener);
            //mMediaPlayer.setOnBufferingUpdateListener(this);
            mCurrentBufferPercentage = 0;                        
            mMediaPlayer.setDataSource(getContext(), mUri);            
            mMediaPlayer.setDisplay(m_holder);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.prepareAsync();
            // we don't set the target state here either, but preserve the
            // target state that was there before.
            mCurrentState = STATE_PREPARING;
            //attachMediaController();
        } catch (Exception ex) {
            Log.w(TAG, "Unable to open content: ", ex);
            //mCurrentState = STATE_ERROR;
            //mTargetState = STATE_ERROR;
            //mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
            return;
        }
//        } catch (ex ex) {
//            Log.w(TAG, "Unable to open content: ", ex);
//            //mCurrentState = STATE_ERROR;
//            //mTargetState = STATE_ERROR;
//            //mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
//            return;
//        }
    }
	
	/*
     * release the media player in any state
     */
    private void release(boolean cleartargetstate) {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
    
    public void setVideoPath(String filepath){
    	//mUri = Uri.parse(path);
    	path = filepath;
    }
    
    public void setVideoURI(Uri uri) {
        setVideoURI(uri, null);
    }

    /**
     * @hide
     */
    public void setVideoURI(Uri uri, Map<String, String> headers) {
        mUri = uri;
        //mHeaders = headers;
        //mSeekWhenPrepared = 0;
        //initVideo();
        m_holder = mPreview.getHolder();
        m_holder.addCallback(holder_callback);
        openVideo();
        //openVideo1();
        requestLayout();
        invalidate();
    }
	
	  public void releaseMediaPlayer() {
	        if (mMediaPlayer != null) {
	            mMediaPlayer.release();
	            mMediaPlayer = null;
	        }
	    }
	  
	  public void pause() {
	        if (isInPlaybackState()) {
	            if (mMediaPlayer.isPlaying()) {
	                mMediaPlayer.pause();
	                mCurrentState = STATE_PAUSED;
	            }
	        }
	        
	        mMediaPlayer.pause();
	        mTargetState = STATE_PAUSED;
	        //int currentPos = mMediaPlayer.getCurrentPosition();	        
	    }
	  
	  public void resume() {
		  int currentPos = mMediaPlayer.getCurrentPosition();
		  if(currentPos < 0) currentPos = 0;
		  mMediaPlayer.seekTo(currentPos);
		  mMediaPlayer.start();
		  mPreview.setBackgroundDrawable(null);
		  
	    }
	 
	public void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
        releaseMediaPlayer();
    }
	
	private void startVideoPlayback() {
	        Log.v("TrungTT", "startVideoPlayback");
	        //holder.setFixedSize(mVideoWidth, mVideoHeight);
	        //Log.i("TrungTT","w:"+mVideoWidth+"h:"+mVideoHeight);
	        //m_holder.setFixedSize(200, 200);
	        mMediaPlayer.start();
	        
	    }
	
	
	public void play(){
		
		//openVideo1();
		
		if (isInPlaybackState()) {
	            mMediaPlayer.start();
	            mCurrentState = STATE_PLAYING;
	        }
	    mTargetState = STATE_PLAYING;
		mPreview.setBackgroundDrawable(null);
	}

	

	public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
		// TODO Auto-generated method stub
//		Log.v("TrungTT", "onVideoSizeChanged called");
//        if (width == 0 || height == 0) {
//            Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
//            return;
//        }
//        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mVideoWidth != 0 && mVideoHeight != 0) {
        	Log.e("TrungTT","video size changed.W:"+width+"H:"+height);
            //startVideoPlayback();
        	
        	m_holder.setFixedSize(mVideoWidth, mVideoHeight);
//            mVideoWidth = mp.getVideoWidth();
//            mVideoHeight = mp.getVideoHeight();
//            if (mVideoWidth != 0 && mVideoHeight != 0) {
//                
//            }
        }
	}

	public void onPrepared(MediaPlayer mp) {
		// TODO Auto-generated method stub
		 Log.d("TrungTT", "onPrepared called");
	        mIsVideoReadyToBePlayed = true;
	        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
	        	//m_holder.setFixedSize(200, 200);
	        	m_holder.setFixedSize(mVideoWidth, mVideoHeight);
	        	mMediaPlayer.start();
	            //startVideoPlayback();
	        }
	}

	
}
